home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX500 / SECT.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  21.7 KB  |  906 lines

  1. /* sect.c */
  2.  
  3. /* 
  4.  * Aug-23-88 jye. Change and add codes so that can be used for MS-DOS
  5.  * Dec-20-89 jye. Free a bug that HDX gives a error message when CD-ROM 
  6.  *                  is busy. 
  7.  */
  8.  
  9. #include "obdefs.h"
  10. #include "osbind.h"
  11. #include "mydefs.h"
  12. #include "part.h"
  13. #include "hdx.h"
  14. #include "addr.h"
  15. #include "error.h"
  16.  
  17. #define    ZBUFSIZ    0x4000        /* about 16k == 32 sectors */
  18. #define    ZCOUNT    (ZBUFSIZ/0x200)    /* ZCOUNT = 32 */
  19. #define MAXUNITS 16            /* max number of logical units */
  20.  
  21. #define PUNINFO struct _punifno
  22. PUNINFO {
  23.         WORD puns;    /* number of physical units */
  24.         BYTE pun[MAXUNITS];
  25.         LONG partition_start[MAXUNITS]; /* offset to partition on */
  26.                                         /* physical unit */
  27. };
  28. extern long ostack;        /* old stack pointer */
  29. extern UWORD errcode();        /* function to return error code */
  30. extern int yesscan;        /* the flag for the func. IBMGPART use */
  31. extern long sptrk;        /* the sector per track */
  32. extern int npart;        /* the number of partitions */
  33. extern int ext;            /* the index of extended partition */
  34. extern int extend;        /* the index of end extended partition */
  35. extern int showmany;    /* the flag for show the too many device alert box */
  36. extern char ttscsi;        /* the flag for SCSI if set */
  37. extern int needscan;    /* TRUE: if it is the first time to scan the units */
  38. extern int athead;        /* the # of data heads on the AT drive */
  39. extern int atcyl;        /* the # of cylinders on the AT drive */
  40. extern int atspt;        /* the # of sectors per track on the AT drive */
  41. extern int noacsi;        /* set for no ACSI drive in the system */
  42. /*
  43.  * Logical-to-dev+partition mapping table.
  44.  */
  45. int nlogdevs;                /* # logical devices */
  46. LOGMAP logmap[EXTRALOGD];    /* logical dev map */
  47. int livedevs[MAXPHYSDEVS];    /* live devs flags; 1: device is alive */
  48. int typedev = 0x0000;        /* if set, driver is a removable driver */
  49. int typedrv = 0x0000;        /* if set, driver is a SCSI driver */
  50. int atexst;                    /* AT drive exists */
  51. int slvexst;                /* AT slave drive exists */
  52. char useblit;                /* set for it is not the stbook drive */
  53.  
  54.  
  55. /*
  56.  * Rebuild logical-to-physical mapping
  57.  * by reading and interpreting the root
  58.  * blocks for all physical devs.
  59.  *
  60.  */
  61.  
  62. rescan(flag, znm)
  63.  
  64. int flag;    /* 0: don't report medium change error; */
  65.             /* non-0: report medium change error; */
  66. int znm;    /* 1: do zero & markbad; 0: do partition & format */
  67.  
  68. {
  69.     int dev, scan=0;
  70.     char buf[512];
  71.     char sendata[16];
  72.     int partno, ret, inqret, i;
  73.     PART *partinfo;
  74.     char mask = 0x80;    /* 7th bit is set on */
  75.     int setmask;
  76.     int maxloop;
  77.  
  78.     noacsi = 1;                /* assume there is no ACSI in the system */
  79.     ostack = Super(NULL);    /* set supervice mode */
  80.     ttscsi = chkscsi();        /* check if SCSI exists */
  81.     delay();
  82.     if ((atexst = chkide()))    { /* AT drive exist */
  83.         if (stbook())    {
  84.             useblit = 0;
  85.         } else {
  86.             useblit = chkblit();
  87.         }
  88.         if ((ret = identify(16, buf)) == OK)    {
  89.             delay();
  90.             /* return the number of cylinder, head, spt */
  91.             gparmfc(&atcyl, &athead, &atspt, buf);
  92.         } else { 
  93.             delay();
  94.             Super(ostack);
  95.             ret = errcode(16);
  96.             if (tsterr(ret) != OK) 
  97.                 return ERROR;
  98.             return (-3);    /* don't have to show the alert box */
  99.         }
  100.     }
  101.     delay();
  102.     /*
  103.     if ((atexst) && (slvexst = slave()))    {  AT slave drive exist 
  104.         if ((ret = identify(17, buf)) == OK)    {
  105.             atscyl = getword(buf+2);
  106.             atshead = getword(buf+6);
  107.             atsspt = getword(buf+12);
  108.             delay();
  109.         } else { 
  110.             delay();
  111.             Super(ostack);
  112.             ret = errcode(17);
  113.             if (tsterr(ret) != OK) 
  114.                 return ERROR;
  115.             return (-3);    don't have to show the alert box
  116.         }
  117.     }
  118.     */
  119.     delay();
  120.     Super(ostack);
  121.     /* set the scent message box */
  122.     if ((needscan) && (ttscsi))
  123.         dsplymsg(scanmsg);
  124.  
  125.     /* disable all logical and physical devs */
  126.     for (dev = 0; dev < EXTRALOGD; ++dev)
  127.         logmap[dev].lm_physdev = -1;
  128.  
  129.     for (dev = 0; dev < MAXPHYSDEVS; ++dev)
  130.         livedevs[dev] = 0;
  131.  
  132.     /*
  133.      * Scan all physical devs
  134.      * and pick up partition structures.
  135.      */
  136.     nlogdevs = 0;
  137.     showmany = 0;
  138.     if (atexst)    {
  139.         maxloop = 18;
  140.         dev = 16;
  141.     } else if (ttscsi)    {
  142.         maxloop = 16;
  143.         dev = 8;
  144.     } else {
  145.         maxloop = 8;
  146.         dev = 0;
  147.     }
  148. rerescan:
  149.     for (; dev < maxloop; ++dev)
  150.     {
  151.  
  152.         if (((dev == 16) && atexst) || ((dev == 17) && slvexst))    {
  153.             if ((ret = getroot(dev, buf, (SECTOR)0)) != 0)    {
  154.                 if (tsterr(ret) != OK)    
  155.                     err(rootread);
  156.                 return(ERROR);
  157.             }
  158.             goto atst;    /* skip and do the at stuff only */
  159.         }
  160.         /* initialize the buffer */
  161.         for (i = 0; i < 16; i++)        {
  162.             sendata[i] = 0;
  163.         }
  164.  
  165.         /* check see the drive is a what kind of drive */
  166.            ostack = Super(NULL);
  167.            delay();
  168.         inqret = inquiry(dev, (WORD)16, sendata);
  169.            delay();
  170.            Super(ostack);
  171.         setmask = 0x0001;
  172.         if (inqret & 0x08)    { /* the device is busy */
  173.             continue;
  174.         }
  175.         /* ret not equal OK, it may be a regular hard drive */
  176.         if (inqret == OK)         {     /* it is not a regular hard drive */
  177.             if (sendata[0])      {    /* it is not a hard drive */
  178.                 continue;
  179.             } else if (sendata[1] & mask)    { /* it is a removable drive */
  180.                 ;            /* don't set the SCSI bit */
  181.             } else {
  182.                   /* it is a SCSI drive */
  183.                 /* set the relative bit, 1 is a SCSI, other is not */
  184.                 typedrv |= setmask << dev;
  185.             }
  186.         }
  187.         if ((ret = getroot(dev, buf, (SECTOR)0)) < 0) {
  188.             if (znm)  rangelog(dev);
  189.             continue;
  190.         } else {        /* ret >= 0 */
  191.             if (ret > 0) {
  192.                 if ((flag) && (tsterr(ret) == OK))    {    
  193.                 /* if non-0, report error if medium changed */
  194.                         erasemsg();
  195.                          return ERROR;
  196.                 }
  197.                 if ((ret = getroot(dev, buf, (SECTOR)0))) {    /* try again */
  198.                     if (ret > 0 && flag && tsterr(ret) == OK)    {
  199.                         erasemsg();
  200.                         return ERROR;
  201.                     } else if ((ret > 0) && (!flag))    {
  202.                         if ((inqret == OK) && (sendata[1] & mask))    { 
  203.                             /* it is a removable drive */
  204.                             /* but forget insert the cartridge */
  205.                             err(instdrv);
  206.                             erasemsg();
  207.                         }
  208.                     }
  209.                     if (znm)    {
  210.                         rangelog(dev);
  211.                     }
  212.                     continue;
  213.                 }
  214.             }
  215.             if (inqret == OK)     {  /* it is a SCSI drive */
  216.                 if (sendata[1] & mask)    { /* it is a removable drive */
  217.                     /* set the relative bit, 1 is a removable, other is not */
  218.                     typedev |= setmask << dev;
  219.                 }
  220.             }
  221.     atst:
  222.             if (dev < 7)    /* there is a ACSI drive in the system */
  223.                 noacsi = 0;
  224.             livedevs[dev] = 1;
  225.             yesscan = 1;
  226.             if (stgpart(dev, buf, (PART *)&partinfo) == ERROR)    {
  227.                 erasemsg();
  228.                 return ERROR;
  229.             }
  230.             if (ext != NO_EXT)    {
  231.                 sortpart(partinfo,SCAN_BS); 
  232.             }
  233.         for (partno = 0; partno < npart; ++partno) {
  234.             if ((partinfo[partno].p_flg & P_EXISTS) &&
  235.                 (partinfo[partno].p_siz != (SECTOR)0) &&
  236.                 (((partinfo[partno].p_id[0] == 'G') &&
  237.                  (partinfo[partno].p_id[1] == 'E') &&
  238.                  (partinfo[partno].p_id[2] == 'M'))   ||
  239.                  ((partinfo[partno].p_id[0] == 'B') &&
  240.                  (partinfo[partno].p_id[1] == 'G') &&
  241.                  (partinfo[partno].p_id[2] == 'M'))))   
  242.             {
  243.                 if (nlogdevs > EXTRALOGD)    {
  244.                     continue;
  245.                 }
  246.                 logmap[nlogdevs].lm_physdev = dev;
  247.                 logmap[nlogdevs].lm_partno = partno;
  248.                 logmap[nlogdevs].lm_start =  partinfo[partno].p_st;
  249.                 logmap[nlogdevs].lm_siz =      partinfo[partno].p_siz;
  250.                 ++nlogdevs;
  251.                 if (nlogdevs == MAXLOGDEVS)         {
  252.                     showmany = 1;
  253.                 }
  254.             }
  255.         }
  256.     }
  257.     inipart(partinfo, npart);
  258.     if (partinfo > 0)    Mfree(partinfo);
  259.     }
  260.  
  261.     if ((maxloop > 16) && (ttscsi))    {
  262.         maxloop = 16;
  263.         dev = 8;
  264.         goto rerescan;
  265.     } else if (((maxloop > 16) && (!ttscsi)) || ((ttscsi)&&(maxloop>8)))    {
  266.         maxloop = 8;
  267.         dev = 0;
  268.         goto rerescan;
  269.     }
  270.     erasemsg();
  271.     return OK;
  272. }
  273.  
  274. /* rerange the partition informations. */
  275.  
  276.  sortpart(pinfo, type)
  277.  PART *pinfo;
  278.  int type;                /* USER_ED = 1: for user interface use */
  279.                          /* SCAN_BS = 0: for rescan() and laybs() use */
  280.  {
  281.      int i, j, k;
  282.     PART rpart[2];
  283.  
  284.     if (ext == NO_EXT) return OK;    /* don't need sort */
  285.     for (i = 0; i < 2; i++)    { /* initialize the temple space */
  286.         rpart[i].p_flg = 0L;
  287.         rpart[i].p_st = 0L;
  288.         rpart[i].p_siz = 0L;
  289.         for (k = 0; k < 3; k++)
  290.             rpart[i].p_id[k] = '0';
  291.     }
  292.     /* save the partitions that after the extened partitions */
  293.     for (i = ext+1, j=0; i < 4; i++, j++)        {
  294.         if (pinfo[i].p_flg & P_EXISTS)    {
  295.             rpart[j].p_flg = P_EXISTS;
  296.             rpart[j].p_st = pinfo[i].p_st;
  297.             rpart[j].p_siz = pinfo[i].p_siz;
  298.             for (k = 0; k < 3; k++)
  299.                 rpart[j].p_id[k] = pinfo[i].p_id[k];
  300.         } 
  301.     }
  302.     /* move the extened partition to the front */
  303.      for (i=4, j = ext; i < npart; i++, j++)    {
  304.         if (pinfo[i].p_flg & P_EXISTS)    {
  305.             pinfo[j].p_flg = P_EXISTS;
  306.             pinfo[j].p_st = (type)?(pinfo[i].p_st):(pinfo[i].p_st + ROOTSECT);
  307.             pinfo[j].p_siz = (type)?(pinfo[i].p_siz):(pinfo[i].p_siz-ROOTSECT);
  308.             for (k = 0; k < 3; k++)
  309.                 pinfo[j].p_id[k] = pinfo[i].p_id[k];
  310.         } else { j--;}    /* stay with that space */
  311.     }
  312.     /* copy the not extended partitions back after the extended partitions */
  313.      for (i=0; i < 2; i++, j++)    {
  314.         if (rpart[i].p_flg & P_EXISTS)    {
  315.             pinfo[j].p_flg = P_EXISTS;
  316.             pinfo[j].p_st = rpart[i].p_st;
  317.             pinfo[j].p_siz = rpart[i].p_siz;
  318.             for (k = 0; k < 3; k++)
  319.                 pinfo[j].p_id[k] = rpart[i].p_id[k];
  320.         } else {j--;}
  321.     }
  322.     for (i = j; i < npart; i++)    { /* set the rest to 0 */
  323.         pinfo[i].p_flg = 0L;
  324.         pinfo[i].p_st = 0L;
  325.         pinfo[i].p_siz = 0L;
  326.         for (k = 0; k < 3; k++)
  327.             pinfo[i].p_id[k] = '0';
  328.     }
  329. }
  330.  
  331.  
  332. /* 
  333.  * check to find out the exist of device
  334.  */
  335.  
  336. rangelog(dev)
  337.  
  338. int dev;
  339.  
  340. {
  341.     PUNINFO *divinfo;
  342.     int devnum;
  343.  
  344.     ostack = Super(NULL);
  345.     divinfo = ((PUNINFO *) *((long *)(0x516)));
  346.     for (devnum = 0; devnum < MAXUNITS; ++devnum)    {
  347.         if ((int)(divinfo->pun[devnum] & 0x07) == dev)    {
  348.             delay();
  349.             nlogdevs++;
  350.         }
  351.     }
  352.     Super(ostack);
  353. }
  354.  
  355. /*
  356.  * From a PHYSICAL device unit (0->7)
  357.  * and a partition number (0->3), figure
  358.  * out the LOGICAL disk number ('C'->'P').
  359.  *
  360.  * return the LOGICAL disk number or
  361.  * ERROR if the PHYSICAL device doesn't exist.
  362.  *
  363.  */
  364. phys2log(pdev, pno)
  365. int  pdev;    /* physical device unit */
  366. int  pno;    /* partition number (0 -> 3) */
  367. {
  368.     int logdev;        /* index to step through partitions of a phys unit */
  369.  
  370.     for (logdev = 0; logdev < EXTRALOGD; logdev++) {
  371.         if (logmap[logdev].lm_physdev == pdev &&
  372.             logmap[logdev].lm_partno == pno)
  373.             return ('C'+logdev);
  374.     }
  375.     return ERROR;
  376. }
  377.  
  378.  
  379. /*
  380.  * Map block on logical device to
  381.  * block on physical device;
  382.  * return ERROR if the logical device
  383.  * doesn't exist.
  384.  */
  385. log2phys(adev, ablk)
  386. int *adev;
  387. SECTOR *ablk;
  388. {
  389.     int dev;
  390.     char xbuf[256];
  391.     
  392.     dev = *adev;
  393.     if (dev >= 0 && dev <= 17)
  394.     return OK;
  395.  
  396.     dev = toupper(dev);
  397.     if (dev >= 'C' && dev <= 
  398.                 ('C'+EXTRALOGD)) /* from C to 't' are 50 logic device */
  399.     {
  400.     dev -= 'C';
  401.     *adev = logmap[dev].lm_physdev;
  402.     *ablk = logmap[dev].lm_start + *ablk;
  403.     return OK;
  404.     }
  405.  
  406.     return ERROR;
  407. }
  408.  
  409.  
  410.  
  411. /*
  412.  * Return physical starting block# of a partition
  413.  *
  414.  */
  415. SECTOR 
  416. logstart(ldev)
  417. int ldev;    /* logical device */
  418. {
  419.     ldev = toupper(ldev);
  420.     if (ldev >= 'C' && ldev <= 
  421.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  422.         ldev -= 'C';
  423.         return (logmap[ldev].lm_start);
  424.     }
  425.     return ERROR;
  426. }
  427.  
  428.  
  429.  
  430. /*
  431.  * Return physical starting block# of a partition's data block.
  432.  *
  433.  */
  434. SECTOR 
  435. logend(ldev)
  436. int ldev;    /* logical device */
  437. {
  438.     ldev = toupper(ldev);
  439.     if (ldev >= 'C' && ldev <= 
  440.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  441.         ldev -= 'C';
  442.         return (logmap[ldev].lm_start+logmap[ldev].lm_siz-1);
  443.     }
  444.     return ERROR;
  445. }
  446.  
  447.  
  448. #define    MFM 17        /* sectors per track for MFM */
  449. #define    RLL 26        /* sectors per track for RLL */
  450.  
  451.  
  452. /*
  453.  * Check if dev's root block is intact.
  454.  * Return number of sectors per track on disk.
  455.  *
  456.  */
  457. chkroot(dev, bs)
  458. int dev;
  459. char *bs;
  460. {
  461.     extern long get3bytes();
  462.     extern long get4bytes();
  463.     SETMODE *mb;
  464.     int i, ret, set, scsidrv, mask=0x0001;
  465.     int page=4, bsiz;
  466.     int head, spt;
  467.     SECTOR size, msiz, cyl;    /* size of media */
  468.     char buf[512], sendata[32];
  469.     long dmaptr, tmpptr;
  470.     char *dmahigh=0xffff8609,
  471.          *dmamid=0xffff860b,
  472.          *dmalow=0xffff860d;
  473.     
  474.     size = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz;
  475.     
  476.     ret = OK;
  477.     if (dev == 16)    {        /* it is a IDE-AT drive */
  478.         msiz = (SECTOR)athead * (SECTOR)atcyl * (SECTOR)atspt;
  479.         if (size != msiz)
  480.             ret = ERROR;
  481.         return(ret);
  482.     } else if (dev > 7)    {    /* it is a scsi drive */
  483.         ostack = Super(NULL);
  484.         delay();
  485.         if ((ret = readcap(dev, 0, (long)0, sendata)) == OK) {
  486.             if (msiz = get4bytes(sendata))    {
  487.                 msiz += 1;
  488.                 delay();
  489.                 Super(ostack);
  490.                 goto chkend;
  491.             } 
  492.         } 
  493.         for (i = 0; i < 32; i++)
  494.             sendata[i] = 0;
  495.         if ((ret = mdsense(dev, 4, 0, 32, sendata)) == OK)    {
  496.             if((msiz=get3bytes(sendata+5)))    {
  497.                         delay();
  498.                         Super(ostack);
  499.                         goto chkend;
  500.             }
  501.         }
  502.         for (i = 0; i < 32; i++)
  503.             sendata[i] = 0;
  504.         if ((ret = mdsense(dev, 0, 0, 16, sendata)) == OK)    {
  505.             if((msiz=get3bytes(sendata+5)))    {
  506.                         delay();
  507.                         Super(ostack);
  508.                         goto chkend;
  509.             }
  510.         }
  511.         for (i = 0; i < 32; i++)
  512.             sendata[i] = 0;
  513.         if ((ret = mdsense(dev, 3, 0, 32, sendata)) == OK)    {
  514.             if((msiz=get3bytes(sendata+5)))    {
  515.                         delay();
  516.                         Super(ostack);
  517.                         goto chkend;
  518.             }
  519.         }
  520.         msiz = size;
  521.         delay();
  522.         Super(ostack);
  523.         goto chkerr;
  524.     }
  525.  
  526.     ostack = Super(NULL);
  527.     /* Get format parameters/ disk size from media */
  528.     set = typedev & (mask << dev);
  529.     scsidrv = typedrv & (mask << dev);
  530.     bsiz = ((set) || (scsidrv)) ? (16) : (22);
  531.     if ((set) || (scsidrv))    {
  532.         for (i = 0; i < 32; i++)
  533.             sendata[i] = 0;
  534.         mdsense(dev, 0, 0, bsiz, sendata);
  535.         if((msiz=get3bytes(sendata+5)))    {
  536.                     delay();
  537.                     Super(ostack);
  538.                     goto chkend;
  539.         }
  540. redopg:
  541.         for (i = 0; i < 32; i++)
  542.             sendata[i] = 0;
  543.         ret = mdsense(dev, page, 0, 32, sendata);/* use page code 4, but get */
  544.                                             /* info from the mdsense header */
  545.         for (i = 0; i < 32; i++)
  546.             if (sendata[i])
  547.                 break;
  548.         if ((i==32) && (page == 4))        {
  549.             page = 3;
  550.             goto redopg;
  551.         } else if (i == 32)    {
  552.             msiz = size;
  553.             delay();
  554.             Super(ostack);
  555.             goto chkend;
  556.         }
  557.         if (!(msiz = get3bytes(sendata+5)))    {
  558.             if (page == 4)    {
  559.                 page = 3;
  560.                 /*
  561.                 cyl = get3bytes(sendata+14);
  562.                 head = *(sendata+17);
  563.                 */
  564.                 goto redopg;
  565.             } else {
  566.                 /*
  567.                 spt = getword(sendata+22);
  568.                 msiz = cyl * head * spt;
  569.                 */
  570.                 msiz = size;
  571.             }
  572.         }
  573.         delay();
  574.         Super(ostack);
  575.         goto chkend;
  576.     } else    {
  577.         ret = mdsense(dev, 0, 0, 22, sendata);
  578.         delay();
  579.         Super(ostack);
  580.  
  581.         /* If full SCSI, will return number of blocks */
  582.         /* on disk at byte 5, 6 and 7.  If Adaptec,   */
  583.         /* will return 0 for number of blocks on disk */
  584.         /* on SCSI. */
  585.  
  586.             if (!(msiz = get3bytes(sendata+5))) {    /* no disk size returned? */
  587.             /* Yup, ie., it's adaptec's.  Interpret as SETMODE structure */
  588.             mb = (SETMODE *)sendata;
  589.             /* get number of cylinders */
  590.             cyl = mb->smd_cc[0];
  591.             cyl <<= 8;
  592.             cyl |= mb->smd_cc[1];
  593.     
  594.             /* get number of heads */
  595.             head = mb->smd_dhc;
  596.     
  597.             msiz = (SECTOR)head * (SECTOR)cyl * MFM;
  598.     
  599.             for (i = 0; i < 20; i++) {
  600.                 if ((ret = rdsects(dev, 1, buf, msiz+i)) == OK) {
  601.                     /* find out whether data has been transferred, by
  602.                           checking if dma pointer has been moved.      */
  603.  
  604.                     ostack = Super(NULL);
  605.                     delay();
  606.                     dmaptr = *dmahigh;
  607.                     dmaptr &= 0x0000003f;
  608.                     dmaptr <<= 16;
  609.                     tmpptr = *dmamid;
  610.                     tmpptr &= 0x000000ff;
  611.                     tmpptr <<= 8;
  612.                     dmaptr |= tmpptr;
  613.                     tmpptr = *dmalow;
  614.                     tmpptr &= 0x000000ff;
  615.                     dmaptr |= tmpptr;
  616.                     delay();
  617.                     Super(ostack);
  618.  
  619.                     if (dmaptr != buf)
  620.                         break;
  621.                    } else {            /* rdsects return an error */
  622.                     if (tsterr(ret) == OK) {
  623.                            break;
  624.                     }
  625.                 }
  626.             }
  627.     
  628.             if (ret == MDMCHGD)        /* check if error occurred */
  629.                 return (ret);
  630.        
  631.             /* Determine if media is MFM or RLL */
  632.             if (i < 20)    {
  633.                 msiz = (SECTOR)head * (SECTOR)cyl * RLL;
  634.                 goto chkend;
  635.             }
  636.         }
  637.     }
  638. chkerr:
  639.     if (ret != 0) {
  640.         ret = errcode(dev);
  641.         if (tsterr(ret) != OK) 
  642.             return ERROR;
  643.         return (-3);    /* don't have to show the alert box */
  644.     }
  645. chkend:
  646.     if (size != msiz)
  647.         ret = ERROR;
  648.     else 
  649.         ret = OK;
  650.         
  651.     return (ret);
  652. }
  653.  
  654. /*
  655.  * Chkparm()
  656.  *    Check if given logical device has the asssumed parameters.
  657.  * Assumptions are:
  658.  *    - 512 bytes/sector
  659.  *    - 2 sectors/cluster
  660.  *    - 1 reserved sector
  661.  *    - 2 FATs
  662.  *
  663.  * Input:
  664.  *    ldev - logical device number ('C' -> 'P').
  665.  *
  666.  * Return:
  667.  *    OK - parameters of partition match the assumptions
  668.  *    ERROR - something went wrong.
  669.  *
  670.  * Comment:
  671.  *    Number of FATs is assumed to be 2.  Cannot check this 
  672.  * because previous version of HDX did not put that in the boot
  673.  * sector.
  674.  */
  675. chkparm(ldev)
  676. int ldev;
  677. {
  678.     char bs[512];        /* boot sector */
  679.     BOOT *boot;            /* boot structure */
  680.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  681.     int ret;
  682.  
  683.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  684.         if (tsterr(ret) != OK)
  685.             err(bootread);
  686.         ret = ERROR;
  687.         goto parmend;
  688.     }    
  689.  
  690.     boot = (BOOT *)bs;
  691.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  692.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  693.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  694.     if (bps % BPS            /* bytes per sector == ratio of 512 ? */
  695.     || res != 1) {            /* num sectors reserved == 1 ? */
  696.     ret = ERROR;            /* Nope, different from assumptions */
  697.     goto parmend;
  698.     }
  699.     
  700.     /* Check if sectors per cluster make sense */
  701.     if (boot->b_spc != 2) {
  702.         ret = ERROR;
  703.         goto parmend;
  704.     }
  705.     
  706.     ret = OK;                /* If yes, return OK */
  707.  
  708. parmend:
  709.     return ret;
  710. }
  711.  
  712.  
  713. ichkparm(ldev)
  714. int ldev;
  715. {
  716.     char bs[512];        /* boot sector */
  717.     BOOT *boot;            /* boot structure */
  718.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  719.     int ret;
  720.  
  721.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  722.         if (tsterr(ret) != OK)
  723.             err(bootread);
  724.         ret = ERROR;
  725.         goto parmend;
  726.     }    
  727.  
  728.     boot = (BOOT *)bs;
  729.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  730.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  731.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  732.     if (bps != 512            /* bytes per sector == 512 ? */
  733.     || res != 1) {            /* num sectors reserved == 1 ? */
  734.     ret = ERROR;            /* Nope, different from assumptions */
  735.     goto parmend;
  736.     }
  737.     
  738.     /* Check if sectors per cluster make sense */
  739.     if ((siz >= 0x8000L && boot->b_spc != 4) ||
  740.         (siz < 0x8000L && boot->b_spc != 2)) {
  741.         ret = ERROR;
  742.         goto parmend;
  743.     }
  744.     
  745.     ret = OK;                /* If yes, return OK */
  746.  
  747. parmend:
  748.     return ret;
  749. }
  750.  
  751.  
  752. /*
  753.  * Get dev's root block.
  754.  *
  755.  */
  756. getroot(dev, buf, sect)
  757. int dev;
  758. char *buf;
  759. SECTOR sect;
  760. {
  761.     return rdsects(dev, 1, buf, sect);
  762. }
  763.  
  764.  
  765. /*
  766.  * Put dev's root block.
  767.  *
  768.  */
  769. putroot(dev, buf, sect)
  770. int dev;
  771. char *buf;
  772. SECTOR sect;
  773. {
  774.     return wrsects(dev, 1, buf, sect);
  775. }
  776.  
  777.  
  778. /*
  779.  *  Read sector(s) from dev.
  780.  *
  781.  *  Input:
  782.  *    dev - device number (logical or physical).
  783.  *    num - number of sectors to read.
  784.  *    buf - buffer to write data read.
  785.  *    sect - starting sector number to read from.
  786.  *
  787.  *  Return:
  788.  *    errnum - 0: if read is successful.
  789.  *         an error code: if read is unsuccessful.
  790.  */
  791. rdsects(dev, num, buf, sect)
  792. int dev;            /* device number (logical or physical) */
  793. UWORD num;            /* number of sectors to read */
  794. char *buf;
  795. SECTOR sect;            /* starting sector to read from */
  796. {
  797.     int errnum;
  798.  
  799.     if (log2phys(&dev, §) < 0)
  800.     return ERROR;
  801.  
  802.     ostack = Super(NULL);
  803.     if (dev == 16)    { /* it is a AT drive */
  804.         errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
  805.     } else {
  806.         errnum = hread(sect, num, buf, (UWORD)dev);
  807.     }
  808.     /*
  809.     if (errnum == 04)    {      the drive is stop 
  810.         delay();
  811.         stunt();
  812.         delay();
  813.         errnum = hread(sect, num, buf, (UWORD)dev);
  814.     }
  815.     */
  816.     delay();
  817.     Super(ostack);
  818.  
  819.     if (errnum > 0) {
  820.         errnum = errcode(dev);
  821.     }
  822.         
  823.     return errnum;        /* return the error code */
  824. }
  825.  
  826.  
  827. /*
  828.  *  Write sector(s) to dev.
  829.  *
  830.  *  Input:
  831.  *    dev - device number (logical or physical).
  832.  *    num - number of sectors to write.
  833.  *    buf - buffer with data to be written.
  834.  *    sect - starting sector number to write to.
  835.  *
  836.  *  Return:
  837.  *    errnum - 0: if write is successful.
  838.  *         an error code: if write is unsuccessful.
  839.  */
  840. wrsects(dev, num, buf, sect)
  841. int dev;            /* device number (logical or physical */
  842. UWORD num;            /* number of sectors to write */
  843. char *buf;            /* buffer with data to be written */
  844. SECTOR sect;            /* starting sector to write to */
  845. {
  846.     int errnum;
  847.  
  848.     if (log2phys(&dev, §) < 0)
  849.     return ERROR;
  850.  
  851.     ostack = Super(NULL);
  852.     if (dev == 16)    { /* it is a AT drive */
  853.         errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
  854.     } else {
  855.         errnum = hwrite(sect, num, buf, (UWORD)dev);
  856.     }
  857.     delay();
  858.     Super(ostack);
  859.  
  860.     if (errnum > 0) {
  861.         errnum = errcode(dev);
  862.     }
  863.  
  864.     return errnum;
  865. }
  866.  
  867.  
  868. /*
  869.  * Zero range of sectors on dev.
  870.  *
  871.  */
  872. zerosect(dev, start, count)
  873. int dev;
  874. SECTOR start;
  875. UWORD count;
  876. {
  877.     char *zbuf;
  878.     int  v;
  879.     UWORD i;
  880.  
  881.     if ((zbuf = (char *)mymalloc(ZBUFSIZ)) <= 0)
  882.         return err(nomemory);
  883.         
  884.     if (log2phys(&dev, &start) < 0) {
  885.         free(zbuf);
  886.     return ERROR;
  887.     }
  888.  
  889.     fillbuf(zbuf, (long)ZBUFSIZ, 0L);
  890.  
  891.     while (count)
  892.     {
  893.         if (count > ZCOUNT)
  894.             i = ZCOUNT;
  895.         else i = count;
  896.  
  897.     if ((v = wrsects(dev, i, zbuf, start)) != 0)
  898.         break;
  899.     start += i;
  900.     count -= i;
  901.     }
  902.     free(zbuf);
  903.     
  904.     return v;
  905. }
  906.